package com.cdtu.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cdtu.entity.*;
import com.cdtu.mapper.TaskMapper;
import com.cdtu.properties.WinXinProperties;
import com.cdtu.service.*;
import com.cdtu.util.HttpClientUtil;
import com.cdtu.util.RedisConst;
import com.cdtu.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.*;

@RestController
@CrossOrigin
public class WxUserController {
    @Autowired
    TaskMapper taskMapper;
    @Autowired
    TaskService taskService;
    @Autowired
    UserService userService;
    @Autowired
    WinXinProperties winXinProperties;
    @Autowired
    HttpClientUtil httpClient;
    @Autowired
    CertifyService certifyService;
    @Autowired
    SpecialityService specialityService;
    @Autowired
    RUserSpecialityService rUserSpecialityService;
    @Autowired
    RUserCertifyService rUserCertifyService;

    @Autowired
    ResourceService resourceService;
    @Autowired
    MessagesService messagesService;
    @Autowired
    LearnRecordService learnRecordService;
    @Autowired
    StudyService studyService;
    @Autowired
    CertifyTypeService certifyTypeService;
    @Autowired
    StringRedisTemplate redisTemplate;
    /**
    *  微信用户通过openid 查看用户的登录或用户的注册
    * @author wp
    * @param
    * @date 2023/2/4 11:11
    * @return
    */
    @GetMapping("/login")
    public R loginOrRegister(@RequestParam("code") String code){
        // 在数据库中查找用户
        String jscode2sessionUrl = winXinProperties.getJscode2sessionUrl()+"?appid="+winXinProperties.getAppid()+"&secret="+winXinProperties.getSecret()+"&js_code="+code+"&grant_type=authorization_code";
        String s = httpClient.sendHttpGet(jscode2sessionUrl);
        System.out.println("ops"+s);
            String openid = JSONUtil.parseObj(s).get("openid").toString();
//        System.out.println(openid);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StrUtil.isBlank(openid),User::getOpenid,openid);
        User user = userService.getOne(queryWrapper);
        if (user!=null) {
            return R.success(user);
        } else {
            //如果不存在就注册用户
           User registerUser= new User();
           long uid = System.currentTimeMillis();
           registerUser.setId(uid);
           registerUser.setOpenid(openid);
           userService.save(registerUser);
           return R.success(registerUser);
        }
    }
 /**
 * 根据用户id查询用参与的全部活动
 * @author wp
 * @param
 * @date 2023/3/3 10:58
 * @return
 */
 @GetMapping("/tasks/{id}")
  public R getUserAllTask(@PathVariable("id") long id){
     List taskIds = taskMapper.getUserByIdAllTaskId(id);
     List<Task> taskList = new ArrayList<>();
     for (Object taskId : taskIds) {
         Task task = taskService.getById((Serializable) taskId);
         taskList.add(task);
     }
     return R.success(taskList);
  }

  /**
  * 根据用户查询用户已完成的活动
  * @author wp
  * @param
  * @date 2023/3/3 14:01
  * @return
  */
  @GetMapping("/tasks/completed/{id}")
  public R getUserCompletedTask(@PathVariable("id") long id){
      List taskIds = taskMapper.getUserByIdCompletedTaskId(id);
      List<Task> taskList = new ArrayList<>();
      for (Object taskId : taskIds) {
          Task task = taskService.getById((Serializable) taskId);
          long dateNow = new Date().getTime();
          if(dateNow>task.getEndTime().getTime()){
          taskList.add(task);
          }
      }
      return R.success(taskList);
  }

    /**
     * 根据用户查询用户进行中的活动
     * @author wp
     * @param
     * @date 2023/3/3 14:01
     * @return
     */
    @GetMapping("/tasks/inProgress/{id}")
    public R getUserInProgressTask(@PathVariable("id") long id){
        List taskIds = taskMapper.getUserByIdInProgressTaskId(id);
        List<Task> taskList = new ArrayList<>();
        for (Object taskId : taskIds) {
            Task task = taskService.getById((Serializable) taskId);
            long dateNow = new Date().getTime();
            if(dateNow < task.getEndTime().getTime() && dateNow>task.getStartTime().getTime()){
                taskList.add(task);
            }
        }
        System.out.println(taskList);
        return R.success(taskList);
    }

    /**
     * 根据用户查询用户待完成的活动
     * @author wp
     * @param
     * @date 2023/3/3 14:01
     * @return
     */
    @GetMapping("/tasks/toStart/{id}")
    public R getUserToStartTask(@PathVariable("id") long id){
        List taskIds = taskMapper.getUserByIdToStartTaskId(id);
        List<Task> taskList = new ArrayList<>();
        for (Object taskId : taskIds) {
            Task task = taskService.getById((Serializable) taskId);
            long dateNow = new Date().getTime();
            if(dateNow<task.getStartTime().getTime()){
                taskList.add(task);
            }
        }
        return R.success(taskList);
    }
    /**
    * 获取推荐用户
    * @author wp
    * @param
    * @date 2023/3/9 21:33
    * @return
    */
    @PostMapping("/tasks/recommend")
    public R recommend(@RequestBody ReUserDto reUserDto){
        String grade = reUserDto.getGrade();
        Long[] certifyId = reUserDto.getActCertify();
        Long[] specialType = reUserDto.getActSpecialType();
        HashSet<User> users = new HashSet<>();
        List<User> list= null;
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        //等级为c则查询所有人
        if ("a".equals(grade)){
            //queryWrapper.eq(!StrUtil.isBlank(openid),User::getOpenid,openid);
            queryWrapper.eq(!StrUtil.isBlank(grade),User::getGrade,grade);
        }  else  if("b".equals(grade)){
            queryWrapper.eq(User::getGrade,grade).or().eq(User::getGrade,"c");
         } else {
              if (certifyId.length == 0 && specialType.length==0){
                  list = userService.list(queryWrapper);
                  return R.success(list);
              }

        }


        list = userService.list(queryWrapper);
        if (certifyId.length == 0 && specialType.length==0){
            return R.success(list);
        }
        ArrayList<Long> list2 = new ArrayList<>();
        for (User user : list) {
            list2.add(user.getId());
        }

        if (certifyId.length>0){
            for (Long id : certifyId) {
                LambdaQueryWrapper<RUserCertify> query = new LambdaQueryWrapper<>();
                query.eq(RUserCertify::getCertifyId,id);
                List<RUserCertify> list3 =rUserCertifyService.list(query);
                if (list3.size()>0){
                    for (RUserCertify ru : list3) {
                        int i = list2.indexOf(ru.getUserId());
                        if (i>=0){
                            users.add(userService.getById(ru.getUserId()));
                        }
                    }
                }
            }
        }
       /* for (Long id : certifyId) {
            List<Long> list1 = userService.finUserByCertifyId(id);

            if (list1.size()>0){
                for (Long rc : list1) {
                    int i = list2.indexOf(rc);
                    if (i>0){
                        users.add(userService.getById(rc));
                    }
                }
            }
        }*/
        if (specialType.length>0){
            for (Long id : specialType) {
                LambdaQueryWrapper<RUserSpeciality> query = new LambdaQueryWrapper<>();
                query.eq(RUserSpeciality::getSpecialityId,id);
                List<RUserSpeciality> list3 = rUserSpecialityService.list(query);
                if (list3.size()>0){
                    for (RUserSpeciality rUserSpeciality : list3) {
                        int i = list2.indexOf(rUserSpeciality.getUserId());
                        if (i>=0){
                            users.add(userService.getById(rUserSpeciality.getUserId()));
                        }
                    }
                }
            }
        }
        return R.success(users);
    }

    /**
    * 获取物质类型级名称
    * @author wp
    * @param
    * @date 2023/3/10 14:33
    * @return
    */
    @GetMapping("/resource")
    public  R getResource(){
        List data = new ArrayList();
        List resources = new ArrayList();
        List resourceData = new ArrayList();
        Set<String> resourceType = new HashSet<>();
        List<Resource> resourceList = resourceService.list();
        if (resourceList.size()>0){
            for (Resource resource : resourceList) {
                resourceType.add(resource.getCategory());
            }
            if (resourceType.size()>0){
                for (String  typeName : resourceType) {
                    List resourceDataItem = new ArrayList();
                    for (Resource resource : resourceList) {
                        if (resource.getCategory().equals(typeName)){
                            resourceDataItem.add(resource.getName());
                        }
                    }
                    resourceData.add(resourceDataItem);
                }
            }
        }
         resources.add(resourceType);
         resources.add(resourceData.get(0));
         data.add(resources);
         data.add(resourceData);
        return R.success(data);
    }

    /**
    * 添加任务
    * @author wp
    * @param
    * @date 2023/3/10 18:20
    * @return
    */
    @Transactional
    @PostMapping("/addTask/{id}")
    public  R addTask(@RequestBody AddTaskVo taskVo,@PathVariable("id") long id){
        long tid = System.currentTimeMillis();
        System.out.println(taskVo);
        Task task = new Task();
        task.setPublishUser(id);
        BeanUtil.copyProperties(taskVo,task);
        task.setId(tid);
        task.setGrade(taskVo.getGrade());
        taskVo.setId(tid);
        task.setPublishTime(new Date());
        boolean result = taskService.save(task);
        if (!result){
            return R.error("发布失败，情重新尝试");
        }
        //任务推送完毕就是存储人员，其实就是给人员发送消息
        List<Long> activeUserList = taskVo.getActiveUserList();
        for (Long o : activeUserList) {
            Messages message=new Messages();
            message.setType(5);
            message.setIdKey(o);
            message.setTime(new Date());
            message.setDescription(taskVo.getDetail());
            boolean save = messagesService.save(message);
            if (!save){
                return R.error("发布失败，情重新尝试");
            }
        }
        //存储这次活动的物质

//        //直接调用物资
//        List<ResourceVO> resourceList = taskVo.getResourceList();
//        for (ResourceVO vo : resourceList) {
//
//        }
        //发送消息完成之后需要将指定参与人员存到缓存中，因为数据库中没有这类人
//        PrepareUser prepareUser=new PrepareUser();
//        prepareUser.setDesignateUserList(taskVo.getDesignateUserList());
        String key = RedisConst.TASK +tid;
        redisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(taskVo));
        return R.success("发布成功");
    }

    /**
    *  根据任务id 编辑任务 编辑任务
    * @author wp
    * @param
    * @date 2023/3/12 10:29
    * @return
    */
    @GetMapping("task/edit/{id}")
    public  R getByIdTask(@PathVariable("id") long id){
        String json = redisTemplate.opsForValue().get(RedisConst.TASK+id);
        if (!StrUtil.hasBlank(json)){
            AddTaskVo addTaskVo = JSONUtil.toBean(json, AddTaskVo.class);
            return R.success(addTaskVo);
        }
        return R.error("数据不存在");
    }

    /**
    *  编辑任务
    * @author wp
    * @param
    * @date 2023/3/12 14:12
    * @return
    */
    @Transactional
    @PostMapping("/editTask/{aid}")
    public  R  editTask(@RequestBody AddTaskVo taskVo,
                        @PathVariable("aid") long aid){
        System.out.println("修改任务");
        System.out.println(aid);
        Task task = new Task();
        BeanUtil.copyProperties(taskVo,task);
        task.setPublishUser(aid);
        task.setPublishTime(new Date());
        boolean update = taskService.updateById(task);
//        boolean update = taskService.saveOrUpdate(task);
        System.out.println(update);
        if (update ){
            redisTemplate.opsForValue().set(RedisConst.TASK+task.getId(),JSONUtil.toJsonStr(taskVo));
            return  R.success("修改成功");
        } else {
            return R.error("修改失败");
        }
    }
    /**
    *  获取用户的学习详情
    * @author wp
    * @param
    * @date 2023/3/16 21:57
    * @return
    */
    @GetMapping("/studyDetail/{uid}/{tid}")
    public R getUserStudyDetail(@PathVariable("uid") long uid, @PathVariable("tid") long tid){
        //去数据库 学习记录查询完成模块的id
        List<LearnRecord> learnRecords = new ArrayList<>();
        ArrayList<StudyDetailDTO> studyDetailDTOArrayList = new ArrayList<>();
       if (tid == 0){
           //查询全部
           LambdaQueryWrapper<LearnRecord> queryWrapper = new LambdaQueryWrapper<>();
           queryWrapper.eq(LearnRecord::getUserId,uid);
          // queryWrapper.eq((LearnRecord::getIsfinished),1);
           learnRecords = learnRecordService.list(queryWrapper);
       } else {
            //根据题目类型查找做题记录
           LambdaQueryWrapper<Study> queryWrapperType = new LambdaQueryWrapper();
           queryWrapperType.eq(Study::getCertifyTypeId, tid);
           List<Study> studyTypeList = studyService.list(queryWrapperType);
           if (studyTypeList.size()>0){
               for (Study study : studyTypeList) {
                    LambdaQueryWrapper<LearnRecord> queryWrapperLearnRecord= new LambdaQueryWrapper<>();
                     queryWrapperLearnRecord.eq(LearnRecord::getStudyId,study.getId());
                   //  queryWrapperLearnRecord.eq(LearnRecord::getIsfinished,1);
                     queryWrapperLearnRecord.eq(LearnRecord::getUserId,uid);
                   LearnRecord one = learnRecordService.getOne(queryWrapperLearnRecord);
                   if (one != null){
                       learnRecords.add(one);
                   }
               }
           }
       }
       if (learnRecords.size()>0){
           for (LearnRecord learnRecord : learnRecords) {
               String type = "";
               String title ="";

               Long studyId = learnRecord.getStudyId();
               LambdaQueryWrapper<Study> queryWrapperStudy = new LambdaQueryWrapper<>();
               LambdaQueryWrapper<Study> eq = queryWrapperStudy.eq(Study::getId, studyId);

               Study study = studyService.getOne(queryWrapperStudy);
               if (study != null){
                   title =study.getTitle();
                   Long certifyTypeId = study.getCertifyTypeId();
                   LambdaQueryWrapper<CertifyType> queryWrapperCertifyType = new LambdaQueryWrapper<>();
                   queryWrapperCertifyType.eq(CertifyType::getId,certifyTypeId);
                   CertifyType certifyType= certifyTypeService.getOne(queryWrapperCertifyType);
                   if (certifyType != null){
                       type = certifyType.getName();
                   }
               }
               // 去缓存里面查询分数和时间
               List<String> topicRecordList = redisTemplate.opsForList().range(RedisConst.TOPIC_RECORD + uid + ":" + studyId, 0, -1);
               if (topicRecordList.size()>0){
                   for (String topicRecord : topicRecordList) {
                       StudyDetailDTO studyDetailDTO = new StudyDetailDTO();
                       studyDetailDTO.setTitle(title);
                       studyDetailDTO.setType(type);
                       ProgressDTO progressDTO = JSONUtil.toBean(topicRecord, ProgressDTO.class);
                       studyDetailDTO.setScore(progressDTO.getSubmitScore());
                       studyDetailDTO.setSubmitTime(progressDTO.getFinishedTime());
                       studyDetailDTOArrayList.add(studyDetailDTO);
                   }
               }
           }
       }
        return  R.success(studyDetailDTOArrayList);
    }

    /**
     *  微信用户通过openid 查看用户的登录或用户的注册
     * @author wp
     * @param
     * @date 2023/2/4 11:11
     * @return
     */
    @GetMapping("/weixin/login")
    public R login(@RequestParam("code") String code){
        // 在数据库中查找用户
//        System.out.println("111111");
//        System.out.println(code);
        String jscode2sessionUrl = winXinProperties.getJscode2sessionUrl()+"?appid="+winXinProperties.getAppid()+"&secret="+winXinProperties.getSecret()+"&js_code="+code+"&grant_type=authorization_code";
        String s = httpClient.sendHttpGet(jscode2sessionUrl);System.out.println(s);
        String session_key = JSONUtil.parseObj(s).get("session_key").toString();
        Map<String,String> map = new HashMap<>();
        map.put("appid",winXinProperties.getAppid());
        String session_key1 = map.put("session_key", session_key);
        return R.success(map);
    }
}


